﻿using Furion.DatabaseAccessor;
using Furion.DatabaseAccessor.Extensions;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Admin.NET.Core;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Microsoft.AspNetCore.Http;
using System.Text;
using System.Web;
using SixLabors.ImageSharp;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;

namespace Admin.NET.Application
{
    /// <summary>
    /// 入库报表
    /// </summary>
    [ApiDescriptionSettings("入库报表", Name = "WareHouseInReportForms", Order = 100)]
    [Route("api/[Controller]")]
    public class WareHouseInReportFormsService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WmsOrder,MasterDbContextLocator> _wmsOrderRep;
        private readonly IRepository<SysDictType, MasterDbContextLocator> _sysDictTypeRep;
        private readonly IRepository<SysDictData, MasterDbContextLocator> _sysDictDataRep;
        private readonly ISysExcelTemplateService _sysExcelTemplateService;
        private readonly static object _lock = new();
        private readonly IRepository<WmsOrderType, MasterDbContextLocator> _wmsOrderTypeRep;
        private readonly IRepository<WmsOrderDetails, MasterDbContextLocator> _wmsOrderDetailsRep;
        private readonly IRepository<WmsPlace, MasterDbContextLocator> _wmsPlaceRep;
        private readonly IRepository<WmsTask, MasterDbContextLocator> _wmsTaskRep;
        private readonly IRepository<WmsTakeMaterialOrder, MasterDbContextLocator> _wmsTakeMaterialOrderRep;
        private readonly IRepository<WmsTakeMaterialOrderDetail, MasterDbContextLocator> _wmsTakeMaterialOrderDetailRep;

        public WareHouseInReportFormsService(
            IRepository<WmsOrder,MasterDbContextLocator> wmsOrderRep
            ,IRepository<SysDictType, MasterDbContextLocator> sysDictTypeRep
            ,IRepository<SysDictData, MasterDbContextLocator> sysDictDataRep
            ,ISysExcelTemplateService sysExcelTemplateService
            ,IRepository<WmsOrderType, MasterDbContextLocator> wmsOrderTypeRep
            ,IRepository<WmsOrderDetails, MasterDbContextLocator> wmsOrderDetailsRep
            ,IRepository<WmsPlace, MasterDbContextLocator> wmsPlaceRep
            ,IRepository<WmsTask, MasterDbContextLocator> wmsTaskRep
            ,IRepository<WmsTakeMaterialOrder, MasterDbContextLocator> wmsTakeMaterialOrderRep
            ,IRepository<WmsTakeMaterialOrderDetail, MasterDbContextLocator> wmsTakeMaterialOrderDetailRep
        )
        {
            _wmsOrderRep = wmsOrderRep;
            _sysDictTypeRep = sysDictTypeRep;
            _sysDictDataRep = sysDictDataRep;
            _sysExcelTemplateService = sysExcelTemplateService;
            _wmsOrderTypeRep = wmsOrderTypeRep;
            _wmsOrderDetailsRep = wmsOrderDetailsRep;
            _wmsPlaceRep = wmsPlaceRep;
            _wmsTaskRep = wmsTaskRep;
            _wmsTakeMaterialOrderDetailRep = wmsTakeMaterialOrderDetailRep;
        }

        /// <summary>
        /// 分页查询入库报表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("GetWareHouseOutReportForms")]
        public async Task<PageResult<GetWareHouseInReportFormsOutput>> GetWareHouseOutReportForms([FromQuery] GetWareHouseInReportFormsInput input)
        {
            //任务表关联领料表
            var pageResult = new PageResult<GetWareHouseInReportFormsOutput>();
            pageResult.PageNo = input.PageNo;
            pageResult.PageSize = input.PageSize;
            var result =from p in _wmsTaskRep.AsQueryable()
            join d in _wmsTakeMaterialOrderDetailRep.AsQueryable() on p.OrderDetailsId equals d.Id
            where p.TaskStatus == TaskStatusEnum.WANCHENG
            select new GetWareHouseInReportFormsOutput
            {
                OID = d.OID,
                Materialcode = d.Materialcode,
                Materialname = d.Materialname,
                Unit = d.Unit,
                Qty = d.Qty,
                DistributeQty = d.DistributeQty,
                SingleLength = d.SingleLength,
                Number = d.Number,
                Batchno_SCM = d.Batchno_SCM,
                Batchno_WMS = d.Batchno_WMS,
                ProjectCode = d.ProjectCode,
                TACode = d.TACode,
                PartCode = d.PartCode,
                ContainerCode = p.ContainerCode,
                PlaceCode = p.SourcePlace,
                CreatedTime = p.CreatedTime,
                Aisle = p.Aisle,
                UpdatedTime = p.UpdatedTime,
            };
            result = result
                .Where(!string.IsNullOrEmpty(input.Materialcode), u => EF.Functions.Like(u.Materialcode, $"%{input.Materialcode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.Materialname), u => EF.Functions.Like(u.Materialname, $"%{input.Materialname.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.Batchno_SCM), u => EF.Functions.Like(u.Batchno_SCM, $"%{input.Batchno_SCM.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.Batchno_WMS), u => EF.Functions.Like(u.Batchno_WMS, $"%{input.Batchno_WMS.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.ProjectCode), u => EF.Functions.Like(u.ProjectCode, $"%{input.ProjectCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.ContainerCode), u => EF.Functions.Like(u.ContainerCode, $"%{input.ContainerCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.PlaceCode), u => EF.Functions.Like(u.PlaceCode, $"%{input.PlaceCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.TACode), u => EF.Functions.Like(u.TACode, $"%{input.TACode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.PartCode), u => EF.Functions.Like(u.PartCode, $"%{input.PartCode.Trim()}%"))
                .Where(input.SearchBeginTime != null && input.SearchEndTime != null, u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                                                                   u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderByDescending(u => u.UpdatedTime);
            pageResult.Rows = result
                .Skip((input.PageNo - 1) * input.PageSize).Take(input.PageSize).Adapt<List<GetWareHouseInReportFormsOutput>>();
            pageResult.TotalRows = result.Count();
            pageResult.TotalPage = (int)Math.Ceiling(pageResult.TotalRows / (double)pageResult.PageSize);
            return pageResult;
        }
    }
}
